/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2011, Salzburg Research. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributor(s):
 * sschaffe
 *
 * File Info:
 * User: sschaffe
 * Date: 2011/01/04
 * Time: 13:19
 *
 * Project: KiWi2, kiwi-core module
 */

package kiwi.core.api.triplestore;

import kiwi.core.exception.NamespaceResolvingException;
import kiwi.core.exception.ResourceResolvingException;
import kiwi.core.model.rdf.*;

import java.util.Collection;
import java.util.List;
import java.util.Locale;

/**
 * A service offering convenience methods for managing and manipulating resources in KiWi. Offers methods for
 * getting/setting properties and listing edges.
 *
 *
 * <p/>
 * User: sschaffe
 */
public interface ResourceService {


    // *****************************************************************************************************
    // methods for creating and removing nodes
    // *****************************************************************************************************


    /**
     * Creates a new KiWiUriResource with a random URI that maps back to this instance of the KiWi 2 system.
     * Stored in the defaultspace.
     * @return
     */
    public KiWiUriResource createUriResource();

    /**
     * Creates a new KiWiUriResource with a random URI that maps back to this instance of the KiWi 2 system.
     * And give this resource the given context (uri of a space)
     *
     * @param context
     * @return
     */
    public KiWiUriResource createUriResource(KiWiUriResource context);



    /**
     * Create a new KiWiUriResource in this knowledge space using the provided uri. Note that resources are not
     * stored unless they are part of a triple. Stored in the defaultspace.
     * @param uri
     * @return
     */
    public KiWiUriResource createUriResource(String uri);

    /**
     * Create a new KiWiUriResource in this knowledge space using the provided uri. Note that resources are not
     * stored unless they are part of a triple. Context define the URIResource of the space.
     *
     * @param uri
     * @param context space of this new resource
     * @return
     */
    public KiWiUriResource createUriResource(String uri, KiWiUriResource context);


    /**
     * Create a new KiWiAnonResource using a new unique identifier.  Note that resources are not stored unless
     * they are part of a triple. Stored in the defaultspace.
     *
     * @return
     */
    public KiWiAnonResource createAnonResource();

    /**
     * Create a new KiWiAnonResource using a new unique identifier.  Note that resources are not stored unless
     * they are part of a triple. Stored in the given context of the knowledgespace.
     *
     * @return
     */
    public KiWiAnonResource createAnonResource(KiWiUriResource context);

    /**
     * Create a new KiWiAnonResource using the provided identifier. If the id is already used, will return the
     * object associated with this id. Note that resources are not stored unless they are part of a triple.
     *
     * @return
     */
    public KiWiAnonResource createAnonResource(String id);

    /**
     * Create a new KiWiAnonResource using a new unique identifier.  Note that resources are not stored unless
     * they are part of a triple. Stored in the given context of the knowledgespace.
     *
     * @return
     */
    public KiWiAnonResource createAnonResource(String id, KiWiUriResource context);


    /**
     * Remove the resource given as argument. The resource is added to the transaction data and marked as
     * deleted when the transaction commits.
     *
     * @param r
     */
    public void removeResource(KiWiResource r);

    /**
     * Create a new KiWiAnonResource using a new unique identifier.  Note that resources are not stored unless
     * they are part of a triple. Stored in the given context of the knowledgespace. It will only remove the triple
     * of the given context. If context null it will remove the context and ALL triples of the resource.
     *
     * @return
     */
    public void removeResource(KiWiResource r, KiWiUriResource context);

    // *****************************************************************************************************
    // methods for retrieving resources
    // *****************************************************************************************************


    /**
     * Retrieve the KiWiUriResource with the given URI if it exists, or return null if it doesn't exist.
     * @param uri
     * @return
     */
    public KiWiUriResource getUriResource(String uri);


    /**
     * Retrieve the KiWiAnonResource with the given ID if it exists, or return null if it doesn't exist.
     * @param id
     * @return
     */
    public KiWiAnonResource getAnonResource(String id);

    /**
     * List all resources contained in the KiWi System, regardless of knowledge space or type.
     *
     * @return
     */
    public Collection<KiWiResource> listResources();


    /**
     * List all resources contained in the KiWi System, regardless of knowledge space or type. Optionally supports
     * paging if limit and offset are given (> 0).
     *
     * @return
     */
    public Collection<KiWiResource> listResources(int offset, int limit);


    public Collection<KiWiResource> listResources(int offset, int limit, KiWiUriResource context);


    /**
     * List all resources of a specific type in the KiWi system.
     *
     * @param type the type of the resources to list
     * @return
     */
    public Collection<KiWiResource> listResources(KiWiResource type);


    /**
     * List all resources contained in a certain knowledge space in the KiWi system.
     *
     * @param space the resource identifying the knowledge space
     * @return
     */
    public Collection<KiWiResource> listResourcesBySpace(KiWiUriResource space);


    /**
     * List all resources of a specific type contained in a certain knowledge space in the KiWi system
     *
     * @param space the resource identifying the knowledge space
     * @param type the type of the resources to list
     * @return
     */
    public Collection<KiWiResource> listResourcesBySpace(KiWiUriResource space, KiWiResource type);


    /**
     * List all resources that have a specific property set.
     *
     * @param propertyUri
     * @param value
     * @return
     */
    public Collection<KiWiResource> listResourcesByProperty(String propertyUri, KiWiNode value);

    /**
     * List all resources that have a specific property set and given space (context)
     *
     * @param propertyUri
     * @param value
     * @param context
     * @return
     */
    public Collection<KiWiResource> listResourcesByProperty(String propertyUri, KiWiNode value, KiWiUriResource context);

    /**
     * List all resources that have a specific property set to the given value
     *
     * @param propertyUri
     * @param value  the literal value to query for
     * @return
     */
    public Collection<KiWiResource> listResourcesByProperty(String propertyUri, String value);

    /**
     * List all resources that have a specific property set to the given value and context
     *
     * @param propertyUri
     * @param value  the literal value to query for
     * @return
     */
    public Collection<KiWiResource> listResourcesByProperty(String propertyUri, String value, KiWiUriResource context);

    // *****************************************************************************************************
    // methods for working with properties
    // *****************************************************************************************************


    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation). Returns only literal
     * values for which no language has been assigned. For all Spaces!!!
     *
     * @param r
     * @param propLabel
     * @return
     */
    public String getProperty(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation). Returns only literal
     * values for which no language has been assigned. Only for properties in the given context.
     *
     * @param r
     * @param propLabel
     * @param context
     * @return
     */
    public String getProperty(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale. For all spaces!!!
     *
     * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
     * @param loc
     * @return
     */
    public String getProperty(KiWiResource r, String propLabel, Locale loc) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale. Just for the given context.
     *
     * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
     * @param loc
     * @return
     */
    public String getProperty(KiWiResource r, String propLabel, Locale loc, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale. For all Spaces!!
     *
     * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
     * @return
     * @throws kiwi.core.exception.NamespaceResolvingException
     */
    public Iterable<String> getProperties(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Generic method to query for literal values related to this resource with the property
     * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale. Just for the given space !!
     *
     * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
     * @return
     * @throws kiwi.core.exception.NamespaceResolvingException
     */
    public Iterable<String> getProperties(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * Generic method to query for literal values related to this resource with the property
	 * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale.
	 *
	 * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long
	 *        form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
	 * @param loc
	 * @return
	 * @throws NamespaceResolvingException
	 */
	public Iterable<String> getProperties(KiWiResource r, String propLabel, Locale loc) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * Generic method to query for literal values related to this resource with the property
	 * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale.
     * Just for the given space !!
	 *
	 * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long
	 *        form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
	 * @param loc
	 * @return
	 * @throws NamespaceResolvingException
	 */
    public Iterable<String> getProperties(KiWiResource r, String propLabel, Locale loc, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;


    /**
     * Generic method to set the literal value of a property of this resource to the provided
     * value without setting a language. For the given context.
     *
     * @param propLabel  the SeRQL or SPARQL short or long notation for the property
     * @param propValue  the String value of this property
     * @throws NamespaceResolvingException
     */
    public void setProperty(KiWiResource r, String propLabel, String propValue, KiWiUriResource context) throws NamespaceResolvingException;

    /**
     * Generic method to set the literal value of a property of this resource to the provided
     * value without setting a language. For all spaces!!!
     *
     * @param propLabel  the SeRQL or SPARQL short or long notation for the property
     * @param propValue  the String value of this property
     * @throws NamespaceResolvingException
     */
    public void setProperty(KiWiResource r, String propLabel, String propValue) throws NamespaceResolvingException;


    /**
     * Generic method to set the literal value of a property of this resource to the provided
     * value in the provided language. For all spaces.
     *
     * @param propLabel  the SeRQL or SPARQL short or long notation for the property
     * @param propValue  the String value of this property
     * @param loc        the Locale representing the language of this property
     * @throws NamespaceResolvingException
     */
    public <T> void setProperty(KiWiResource r, String propLabel, T propValue, Locale loc) throws NamespaceResolvingException;

    /**
	 * Generic method to query for literal values related to this resource with the property
	 * identified by "propLabel" (SeRQL/SPARQL short or long notation) and the given locale.
     * context define the knowledgespace in which this operation is. For the given context.
	 *
	 * @param propLabel label of the property; either RDF short form (e.g. "foaf:mbox") or long
	 *        form (e.g. <http://xmlns.com/foaf/0.1/mbox>)
	 * @param loc
     * @param context context in which this property will set
	 * @return
	 * @throws NamespaceResolvingException
	 */
    public <T> void setProperty(KiWiResource r, String propLabel, T propValue, Locale loc, KiWiUriResource context) throws NamespaceResolvingException;


    /**
     * Remove a property from the KiWiResource.
     *
     * @param propLabel the property label in SeRQL syntax to remove
     * @return true if the property existed and was removed
     * @throws NamespaceResolvingException
     */
    public boolean removeProperty(KiWiResource r, String propLabel) throws NamespaceResolvingException;

    /**
     * Remove a property from the KiWiResource. Just for the given space!!!
     *
     * @param propLabel the property label in SeRQL syntax to remove
     * @return true if the property existed and was removed
     * @throws NamespaceResolvingException
     */
    public boolean removeProperty(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException;

    /**
     * Remove a property from the KiWiResource. Just for the given space!!!
     *
     * @param propLabel the property label in SeRQL syntax to remove
     * @return true if the property existed and was removed
     * @throws NamespaceResolvingException
     */
    public boolean removeProperty(KiWiResource r, String propLabel, Locale loc, KiWiUriResource context) throws NamespaceResolvingException;

    /**
     * Remove a property from the KiWiResource. for all spaces !!!
     *
     * @param propLabel the property label in SeRQL syntax to remove
     * @param loc the locale of the property to remove
     * @return true if the property existed and was removed
     * @throws NamespaceResolvingException
     */
    public boolean removeProperty(KiWiResource r, String propLabel, Locale loc) throws NamespaceResolvingException;



    /* incoming and outgoing edges (KiWiTriple) */

    /**
     * List all outgoing edges from this resource to other resources. Shortcut for listOutgoing(null).
     * For all spaces!!!
     *
     * @return all outgoing edges from this resource
     */
    public List<KiWiTriple> listOutgoing(KiWiResource r);

    /**
     * List all outgoing edges from this resource to other resources. Shortcut for listOutgoing(null).
     * Just for the given space
     *
     * @return all outgoing edges from this resource
     */
    public List<KiWiTriple> listOutgoing(KiWiResource r, KiWiUriResource context);



    /**
     * List outgoing edges from this resource to other resources, using the property label passed
     * as argument. If limit is bigger than 0, then a maximum of limit triples will be returned.
     * Otherwise, all triples will be returned.
     * <p>
     * The parameter propLabel is in the form of a SeRQL or SPARQL id. It can take one of the following
     * values:
     * <ul>
     * <li>a URI enclosed in &lt; &gt, e.g. &lt;http://www.example.com/myProp&gt;</li>
     * <li>a uri prefix, followed by a colon and the property name, e.g. ex:myProp</li>
     * <li>the value "null", in which case all outgoing edges are listed regardless of their label
     * (wildcard)</li>
     * </ul>
     * The result will be an iterable that allows to iterate over KiWiTriples.
     *
     * @param propLabel the label of the property to be queried, or null for wildcard
     * @return an iterable over the KiWiTriples that are outgoing edges of this resource
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listOutgoing(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;


    /**
     * List outgoing edges from this resource to other resources, using the property label passed
     * as argument. If limit is bigger than 0, then a maximum of limit triples will be returned.
     * Otherwise, all triples will be returned.
     * <p>
     * The parameter propLabel is in the form of a SeRQL or SPARQL id. It can take one of the following
     * values:
     * <ul>
     * <li>a URI enclosed in &lt; &gt, e.g. &lt;http://www.example.com/myProp&gt;</li>
     * <li>a uri prefix, followed by a colon and the property name, e.g. ex:myProp</li>
     * <li>the value "null", in which case all outgoing edges are listed regardless of their label
     * (wildcard)</li>
     * </ul>
     * The result will be an iterable that allows to iterate over KiWiTriples.
     * Just for the given space!!!
     *
     * @param propLabel the label of the property to be queried, or null for wildcard
     * @param context outgoing triples just for the given space
     * @return an iterable over the KiWiTriples that are outgoing edges of this resource
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listOutgoing(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * List the objects that are related to this resource through a certain property
	 * @return a list of all outgoingnodes independent of a space
	 * @throws NamespaceResolvingException
	 */
	public Iterable<KiWiNode> listOutgoingNodes(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * List the objects that are related to this resource through a certain property
	 * @return a list of all outgoingnodes dependent of a space
	 * @throws NamespaceResolvingException
	 */
    public Iterable<KiWiNode> listOutgoingNodes(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;


    /**
     * Set the edge identified by propLabel to the node passed as target. All existing edges with propLabel will
     * be deleted.
     *
     * @param propLabel
     * @param target
     * @param <C>
     * @throws NamespaceResolvingException
     */
    public <C extends KiWiNode> void setOutgoingNode(KiWiResource r, String propLabel, C target) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * Set the edge identified by propLabel to the node passed as target. All existing edges with propLabel will
     * be deleted. just for the given context(knowledgespace)
     *
     * @param propLabel
     * @param target
     * @param <C>
     * @param context just for the given context!!!
     * @throws NamespaceResolvingException
     */
    public <C extends KiWiNode> void setOutgoingNode(KiWiResource r, String propLabel, C target, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;
    /**
     * Add an edge between the resource r and the resource target, using propLabel as identifier
     *
     * @param r
     * @param propLabel
     * @param target
     * @throws NamespaceResolvingException
     */
    public void addOutgoingNode(KiWiResource r, String propLabel, KiWiNode target) throws NamespaceResolvingException;



    public void addOutgoingNode(KiWiResource r, KiWiUriResource prop, KiWiNode target) throws NamespaceResolvingException;


    public void removeOutgoingNode(KiWiResource r, String propLabel, KiWiResource target) throws NamespaceResolvingException;

    public void addOutgoingNode(KiWiResource r, String propLabel, KiWiNode target, KiWiUriResource context) throws NamespaceResolvingException;

    public void addOutgoingNode(KiWiResource r, KiWiUriResource prop, KiWiNode target, KiWiUriResource context) throws NamespaceResolvingException;

    public void removeOutgoingNode(KiWiResource r, String propLabel, KiWiResource target, KiWiUriResource context) throws NamespaceResolvingException;

    /**
     * List all incoming edges from other resources to this resource
     * @return
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listIncoming(KiWiResource r);

    /**
     * List all incoming edges from other resources to this resource. Just for the given space(context)
     * @return
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listIncoming(KiWiResource r, KiWiUriResource context);


    /**
     * List incoming edges from other resources to this resource, using the property label passed
     * as argument. If limit is bigger than 0, then a maximum of limit triples will be returned.
     * Otherwise, all triples will be returned.
     * <p>
     * The parameter propLabel is in the form of a SeRQL or SPARQL id. It can take one of the following
     * values:
     * <ul>
     * <li>a URI enclosed in &lt; &gt, e.g. &lt;http://www.example.com/myProp&gt;</li>
     * <li>a uri prefix, followed by a colon and the property name, e.g. ex:myProp</li>
     * <li>the value "null", in which case all outgoing edges are listed regardless of their label
     * (wildcard)</li>
     * </ul>
     * The result will be an iterable that allows to iterate over KiWiTriples.
     *
     * @param propLabel the label of the property to be queried, or null for wildcard
     * @param r the maximum number of triples to retrieve
     * @return an iterable over the KiWiTriples that are incoming edges of this resource
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listIncoming(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;

    /**
     * List incoming edges from other resources to this resource, using the property label passed
     * as argument. If limit is bigger than 0, then a maximum of limit triples will be returned.
     * Otherwise, all triples will be returned.
     * <p>
     * The parameter propLabel is in the form of a SeRQL or SPARQL id. It can take one of the following
     * values:
     * <ul>
     * <li>a URI enclosed in &lt; &gt, e.g. &lt;http://www.example.com/myProp&gt;</li>
     * <li>a uri prefix, followed by a colon and the property name, e.g. ex:myProp</li>
     * <li>the value "null", in which case all outgoing edges are listed regardless of their label
     * (wildcard)</li>
     * </ul>
     * The result will be an iterable that allows to iterate over KiWiTriples.
     *
     * @param propLabel the label of the property to be queried, or null for wildcard
     * @param r the maximum number of triples to retrieve
     * @param context incoming resources just for the given context/space
     * @return an iterable over the KiWiTriples that are incoming edges of this resource
     * @throws NamespaceResolvingException
     */
    public List<KiWiTriple> listIncoming(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * Return a list of nodes that are the sources for edges with propLabel that have this resource
	 * as endpoint. This is mostly a convenience method that wraps listIncoming(propLabel).
	 *
	 * @param propLabel the label that all edges listed must have, or null for wildcard
	 * @return a list of resources that are sources of edges that have this resource as endpoint
	 * @throws NamespaceResolvingException
	 */
	public Iterable<KiWiResource> listIncomingNodes(KiWiResource r, String propLabel) throws NamespaceResolvingException, ResourceResolvingException;

    /**
	 * Return a list of nodes that are the sources for edges with propLabel that have this resource
	 * as endpoint. This is mostly a convenience method that wraps listIncoming(propLabel).
	 *
	 * @param propLabel the label that all edges listed must have, or null for wildcard
	 * @param context the context of the incoming nodes
	 * @return a list of resources that are sources of edges that have this resource as endpoint
	 * @throws NamespaceResolvingException
	 */
    public Iterable<KiWiResource> listIncomingNodes(KiWiResource r, String propLabel, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;



    public void addIncomingNode(KiWiResource r, String propLabel, KiWiResource source) throws NamespaceResolvingException, ResourceResolvingException;
    public void addIncomingNode(KiWiResource r, String propLabel, KiWiResource source, KiWiUriResource context) throws NamespaceResolvingException, ResourceResolvingException;



    /* convenience wrappers around common RDF properties */

    /**
     * Return the label of this resource in the language provided as parameter
     *
     * If no label is available for the given language, returns the identifier.
     *
     * @return
     */
    public String getLabel(KiWiResource r);

    /**
     * Return the label of this resource in the language provided as parameter
     *
     * If no label is available for the given language, returns the identifier.
     * @param context   the space of the label
     * @return
     */
    public String getLabel(KiWiResource r, KiWiUriResource context);



    /**
     * Return the label of this resource in the language provided as parameter
     * within the getTripleStore().knowledge space of this KiWiResource.
     *
     * If no label is available for the given language, returns the identifier.
     * Looking in all spaces!!!
     *
     * @param loc
     * @return
     */
    public String getLabel(KiWiResource r, Locale loc);

    /**
     * Return the label of this resource in the language provided as parameter
     * within the getTripleStore().knowledge space of this KiWiResource.
     *
     * If no label is available for the given language, returns the identifier.
     *
     * @param context space of the given label
     * @param loc
     * @return
     */
    public String getLabel(KiWiResource r, Locale loc, KiWiUriResource context);



    /**
     * Set the rdfs:label of this KiWiResource in the configured getTripleStore().TripleStore
     * for the given Locale. Looking in all spaces!!!
     *
     * @param loc
     * @param label
     * @throws NamespaceResolvingException
     */
    public void setLabel(KiWiResource r, Locale loc, String label);

    /**
     * Set the rdfs:label of this KiWiResource in the configured getTripleStore().TripleStore
     * for the given Locale. Just for the given space !!!
     *
     * @param loc
     * @param label
     * @param context
     * @throws NamespaceResolvingException
     */
    public void setLabel(KiWiResource r, Locale loc, String label, KiWiUriResource context);



    /**
     * Return the rdfs:comment for this resource for the given locale
     * @param loc
     */
    public String getComment(KiWiResource r, Locale loc);

    /**
     * Return the rdfs:comment for this resource for the given locale in the given knowledgespace (context)
     * @param context
     * @param loc
     */
    public String getComment(KiWiResource r, Locale loc, KiWiUriResource context);


    /**
     * Set the rdfs:comment for this resource
     * @param loc
     * @param comment
     */
    public void setComment(KiWiResource r, Locale loc, String comment);

    /**
     * Set the rdfs:comment for this resource. And the given context/space!!!
     *
     * @param loc
     * @param context
     * @param comment
     */
    public void setComment(KiWiResource r, Locale loc, String comment, KiWiUriResource context);


    /**
     * Return the list of types as KiWiResources that are associated with this resource using the
     * rdf:type RDF property.
     *
     * @return an iterable of KiWiResource instances that represent the RDF types of this resource
     */
    public Collection<KiWiResource> getTypes(KiWiResource r);

    /**
     * Return the list of types as KiWiResources that are associated with this resource using the
     * rdf:type RDF property.
     *
     * @return an iterable of KiWiResource instances that represent the RDF types of this resource
     */
    public Collection<KiWiResource> getTypes(KiWiResource r, KiWiUriResource context);

    /**
     * Add a new type to the list of RDF types of this KiWiResource. And add it to the given context!!!
     *
     * @param type the type to add
     */
    public void addType(KiWiResource r, KiWiResource type, KiWiUriResource context);

    /**
     * Add a new type to the list of RDF types of this KiWiResource.
     *
     * @param type the type to add
     */
    public void addType(KiWiResource r, KiWiResource type);



    /**
     * Remove one of the RDF types of this KiWiResource
     * @param type a URI resource representing the type of this KiWiResource
     */
    public void removeType(KiWiResource r, KiWiResource type);

    /**
     * Remove one of the RDF types of this KiWiResource. Just for the given context!!!
     *
     * @param type a URI resource representing the type of this KiWiResource
     */
    public void removeType(KiWiResource r, KiWiResource type, KiWiUriResource context);

    /**
     * Remove one of the RDF types of this KiWiResource. For all spaces/context
     *
     * @param typeUri a URI resource representing the type of this KiWiResource
     */
    public boolean hasType(KiWiResource r, String typeUri);

    /**
     * Remove one of the RDF types of this KiWiResource. Just for the given context!!!
     *
     * @param typeUri a URI resource representing the type of this KiWiResource
     * @param context a URI resource representing the type of this KiWiResource
     *
     */
    public boolean hasType(KiWiResource r, String typeUri, KiWiUriResource context);


    /**
     * Check whether this KiWiResource has a certain RDF type
     * @param type the resource representing the type to check for
     * @return true if the type is in the list of RDF types of this resource, false otherwise
     */
    public boolean hasType(KiWiResource r, KiWiUriResource type);

    /**
     * Check whether this KiWiResource has a certain RDF type in the given context/space
     *
     * @param type the resource representing the type to check for
     * @return true if the type is in the list of RDF types of this resource, false otherwise
     */
    public boolean hasType(KiWiResource r, KiWiUriResource type, KiWiUriResource context);


    public void clearCaches();
}
